﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;

namespace TrailBlockMod
{
    class ribbonScript : MonoBehaviour
    {

        public int Length { get; set; }
        public float StartWidth { get; set; }
        public float EndWidth { get; set; }

        public MeshRenderer renderer { get { return go.GetComponent<MeshRenderer>(); } private set { } }
        public Material material { get { return renderer.material; }private set { } }

        private Mesh ribbonMesh;//条带网格
        private Vector3[] vertices;       //顶点
        private Vector2[] uvs;   //uv
        private int[] triangles; //三角索引

        //彩带经过的点
        private RibbonPoint[] points;
        private GameObject go;

        public class RibbonPoint
        {
            public Vector3 position;
            public Vector3 direction;

            public Vector3 leftPoint { get; private set; }
            public Vector3 rightPoint { get; private set; }

            public RibbonPoint()
            {
                leftPoint = Vector3.zero;
                rightPoint = Vector3.zero;
            }

            public RibbonPoint(Transform transform, float width)
            {
                position = transform.position;
                direction = transform.right;

                ResetWidth(width);
            }

            public RibbonPoint(Vector3 position, Vector3 direction, float width)
            {
                this.position = position;
                this.direction = direction;

                ResetWidth(width);
            }
 
            public void ResetWidth(float width)
            {
                var offset = direction * width * 0.5f;

                leftPoint = position + offset;
                rightPoint = position - offset;
            }
        }

        void Awake()
        {
            go = new GameObject("Ribbon Renderer");
            var mct = GameObject.Find("Main Camera").transform;
            go.transform.SetParent(mct);
            go.transform.position = mct.position + mct.forward * 3f;
            go.transform.localScale = Vector3.one * 0.001f;

            go.AddComponent<MeshFilter>();          
            renderer = go.AddComponent<MeshRenderer>();
            material = renderer.material;
        }

        void Start()
        {  
            points = new RibbonPoint[Length];
            for (int i = 0; i < Length; i++)
            {
                points[i] = new RibbonPoint(transform, 0f);
            }

            ribbonMesh = go.GetComponent<MeshFilter>().mesh;  //mesh是依附在gameobject上的
            ribbonMesh.Clear();
            ribbonInit();       
        }


        void Update()
        {
            for (int i = 0; i < Length; i++)
            {
                if (i == Length - 1)
                {
                    points[i] = new RibbonPoint(transform, StartWidth);             
                }
                else
                {
                    points[i] = points[i + 1];
                }

                var width = Mathf.Lerp(StartWidth, EndWidth, 1f - (i / ((float)(Length - 1))));
                points[i].ResetWidth(width);

                vertices[2 * i] = go.transform.InverseTransformPoint(points[i].leftPoint);
                vertices[2 * i + 1] = go.transform.InverseTransformPoint(points[i].rightPoint);
            }

            ribbonMesh.vertices = vertices;


        }

        void OnDestroy()
        {
            Destroy(go);
        }

        private void ribbonInit()
        {

            vertices = new Vector3[2 * points.Length]; //顶点
            uvs = new Vector2[vertices.Length];  //uv
            triangles = new int[(vertices.Length - 2) * 3]; //三角索引

            for (var i = 0; i < Length; i++)
            {
                vertices[2 * i] = points[i].leftPoint;
                vertices[2 * i + 1] = points[i].rightPoint;

                uvs[2 * i] = new Vector2(i / (Length - 1.0f), 1);
                uvs[2 * i + 1] = new Vector2(i / (Length - 1.0f), 0);
            }

            int tranglesNumber = (vertices.Length - 2);

            int trangleIndex = 0;
            for (var j = 0; j < tranglesNumber; j = j + 2)
            {
                triangles[trangleIndex++] = j;
                triangles[trangleIndex++] = j + 3;
                triangles[trangleIndex++] = j + 1;

                triangles[trangleIndex++] = j;
                triangles[trangleIndex++] = j + 2;
                triangles[trangleIndex++] = j + 3;
            }

            ribbonMesh.vertices = vertices;
            ribbonMesh.uv = uvs;
            ribbonMesh.triangles = triangles;

        }



    }
}
